<template>
<!--  TODO GPT和百度语音演示 要用的时候代码直接抄就行了-->

  <div style="margin-left: 10px;margin-top: 10px">
    <el-row style="margin-left: 15px">
      <el-button type="primary" @click="recOpen">请求录音权限</el-button>
      <el-button type="primary" @click="recStart">开始录音</el-button>
      <el-button type="primary" @click="recStop">结束录音</el-button>

      <el-button type="primary" @click="speechToText">语音转文字</el-button>
      <el-button type="primary" @click="simpleMatter" style="margin-left: 50px">发送极简事项</el-button>
      <span style="position: relative;top:10px;font-weight: 700;">——</span>
      <el-radio-group v-model="form.mode">
        <el-radio-button label="0" >自定义</el-radio-button>
        <el-radio-button label="1" >润色语句</el-radio-button>
        <el-radio-button label="2" >总结语句</el-radio-button>
      </el-radio-group>
    </el-row>
    <el-row style="margin-top: 20px;margin-left: 15px;">
      <el-col :span="8">
        <el-input
            v-model="form.text"
            maxlength="2000"
            show-word-limit
            :autosize="{ minRows: 4, maxRows: 8 }"
            type="textarea"
            placeholder="收费,慎用,模型GPT-3.5-turbo-4k,效果不满意建议GPT-4-4k 但是价格 翻6倍"
        />
      </el-col>
      <el-col :span="8">
        <el-button type="primary" @click="sendMsg">发送消息</el-button>
        <el-button type="primary" @click="msgList = []">清屏</el-button>
      </el-col>
    </el-row>
    <div class="page-container">
      <el-card class="box-card" v-for="item in msgList" style="margin-top: 10px">
        <el-row>
          <div class="container">
            <div class="container-name">
              {{item.name}}
            </div>

            <div class="container-msg" v-if="item.name === '音频文件：'">
              <audio :src="item.msg" controls="controls" preload id="audio" />
            </div>
            <div class="container-msg" v-else>
              {{item.msg}}
            </div>

            <div class="container-date">
              {{item.date}}
            </div>
          </div>
        </el-row>
      </el-card>
    </div>
  </div>
</template>

<script>
import socketGPT from './socket-gpt'
//必须引入的核心
import Recorder from 'recorder-core'
//引入mp3格式支持文件；如果需要多个格式支持，把这些格式的编码引擎js文件放到后面统统引入进来即可
// import 'recorder-core/src/engine/mp3'
// import 'recorder-core/src/engine/mp3-engine'
//录制wav格式的用这一句就行
import 'recorder-core/src/engine/wav'


import {onMounted, reactive, ref, toRefs} from "vue";
import {sendOneMsgByStream, simpleWork, speechToTextByBaiDu} from "../../../api/gpt";
import {useUserInfo} from "../../../stores/userInfo";
import {formatDate} from "../../../utils/formatTime";

export default {
  name: "index",
  setup(props, context) {
    const storesUserInfo = useUserInfo()
    const state = reactive({
      socket:null,
      rec:null,
      msgList:[],
      recBlob:null,
      form:{
        text:'',
        mode:'0',
      }
    })

    const recOpen = () => {
      //创建录音对象
      state.rec=Recorder({
        type:"wav" //录音格式 默认mp3
        ,sampleRate:16000 //录音的采样率，越大细节越丰富越细腻
        ,bitRate:16 //录音的比特率，越大音质越好
        ,onProcess:(buffers,powerLevel,bufferDuration,bufferSampleRate,newBufferIdx,asyncEnd)=>{
          //录音实时回调，大约1秒调用12次本回调
          //可实时绘制波形，实时上传（发送）数据
          // if(this.wave) {
          //   this.wave.input(buffers[buffers.length-1],powerLevel,bufferSampleRate)
          // }
        }
      });

      //打开录音，获得权限
      state.rec.open(()=>{
        state.msgList.push({
          name:"系统消息：",
          date:formatDate(new Date(),"YYYY-mm-dd HH:MM:SS WWW"),
          msg:"录音权限已获取"
        })

      },(msg,isUserNotAllow)=>{
        //用户拒绝了录音权限，或者浏览器不支持录音
        state.msgList.push({
          name:"系统消息：",
          date:formatDate(new Date(),"YYYY-mm-dd HH:MM:SS WWW"),
          msg:"无法录音:"+msg
        })
        console.log((isUserNotAllow?"UserNotAllow，":"")+"无法录音:"+msg);
      });
    }

    const recStart = () => {
      if(!state.rec){
        state.msgList.push({
          name:"系统消息：",
          date:formatDate(new Date(),"YYYY-mm-dd HH:MM:SS WWW"),
          msg:"未打开录音"
        })
        console.error("未打开录音");return
      }
      state.rec.start();
      state.msgList.push({
        name:"系统消息：",
        date:formatDate(new Date(),"YYYY-mm-dd HH:MM:SS WWW"),
        msg:"已开始录音"
      })
      console.log("已开始录音");
    }

    const recStop = () => {
      if(!state.rec){
        state.rec=null;
        state.msgList.push({
          name:"系统消息：",
          date:formatDate(new Date(),"YYYY-mm-dd HH:MM:SS WWW"),
          msg:"未打开录音"
        })
        console.error("未打开录音");return
      }
      state.rec.stop((blob,duration)=>{
        //blob就是我们要的录音文件对象，可以上传，或者本地播放
        state.recBlob=blob;
        //简单利用URL生成本地文件地址，此地址只能本地使用，比如赋值给audio.src进行播放，赋值给a.href然后a.click()进行下载（a需提供download="xxx.mp3"属性）
        var localUrl=(window.URL||webkitURL).createObjectURL(blob);
        console.log("录音成功",blob,localUrl,"时长:"+duration+"ms");
        state.msgList.push({
          name:"音频文件：",
          date:formatDate(new Date(),"YYYY-mm-dd HH:MM:SS WWW"),
          msg:localUrl
        })
        console.log(state.recBlob)
        // upload(blob);//把blob文件上传到服务器

        state.rec.close();//关闭录音，释放录音资源，当然可以不释放，后面可以连续调用start
        state.rec=null;
      },(err)=>{
        state.msgList.push({
          name:"系统消息：",
          date:formatDate(new Date(),"YYYY-mm-dd HH:MM:SS WWW"),
          msg:"结束录音出错"
        })
        console.error("结束录音出错："+err);
        state.rec.close();//关闭录音，释放录音资源，当然可以不释放，后面可以连续调用start
        state.rec=null;
      });
    }

    //发送消息到GPT
    const sendMsg = () => {
      if(state.form.text !== "" && state.form.text != null){
        state.msgList.push({
          name:"我的消息：",
          date:formatDate(new Date(),"YYYY-mm-dd HH:MM:SS WWW"),
          msg:state.form.text
        })
        state.form.text = ""
        sendOneMsgByStream({message:state.form.text}).then(res =>{
          if(res.code === 0){
            state.msgList.push({
              name:"GPT消息：",
              date:formatDate(new Date(),"YYYY-mm-dd HH:MM:SS WWW"),
              msg:""
            })
          }
        })
      }else{
        alert("不可以为空")
      }
    }

    //百度语音转文字
    const speechToText = () => {
      if(state.recBlob != null){
        speechToTextByBaiDu({file:state.recBlob,type:"wav"}).then(res =>{
          if(res.code === 0){
            let data = JSON.parse(res.data)
            state.msgList.push({
              name:"百度语音消息：",
              date:formatDate(new Date(),"YYYY-mm-dd HH:MM:SS WWW"),
              msg:data.result[0]
            })
          }
        })
      }else {
        state.msgList.push({
          name:"系统消息：",
          date:formatDate(new Date(),"YYYY-mm-dd HH:MM:SS WWW"),
          msg:"没有音频数据"
        })
      }
    }

    //极简事项
    const simpleMatter = () => {
      if(state.recBlob != null){
        simpleWork({file:state.recBlob,type:"wav",mode:state.form.mode}).then(res =>{

        })
      }else {
        state.msgList.push({
          name:"系统消息：",
          date:formatDate(new Date(),"YYYY-mm-dd HH:MM:SS WWW"),
          msg:"没有音频数据"
        })
      }
    }

    onMounted(() => {
      state.msgList.push({
        name:"系统消息：",
        date:formatDate(new Date(),"YYYY-mm-dd HH:MM:SS WWW"),
        msg:"welcome"
      })
      socketGPT.connect()
      socketGPT.socket.on('onMessage', (data, orginData) => {
        let openAiData = JSON.parse(orginData)
        openAiData.data = openAiData.data.replace(/\\n/g, '\n');
        state.msgList[state.msgList.length - 1].msg += openAiData.data
      })

    })

    return{
      ...toRefs(state),
      recOpen,
      recStart,
      recStop,
      sendMsg,
      speechToText,
      simpleMatter,

    }

  }
}
</script>

<style scoped lang="scss">
.container{

  .container-date{
    font-size: 12px;
  }

  .container-msg{
    margin-left: 10px;
    padding: 5px 5px;
    line-height: 30px;
    white-space: pre-wrap;
    font-weight: 700;
    color: #666;
    background-color: transparent;
  }

  .container-name{
    font-weight: 700;
  }
}
</style>
